home *** CD-ROM | disk | FTP | other *** search
/ Amiga Tools 2 / Amiga Tools 2.iso / tools / packer / ha0999beta / src / acoder.c next >
C/C++ Source or Header  |  1995-03-09  |  6KB  |  361 lines

  1. /***********************************************************************
  2.   This file is part of HA, a general purpose file archiver.
  3.   Copyright (C) 1995 Harri Hirvola
  4.  
  5.   This program is free software; you can redistribute it and/or modify
  6.   it under the terms of the GNU General Public License as published by
  7.   the Free Software Foundation; either version 2 of the License, or
  8.   (at your option) any later version.
  9.  
  10.   This program is distributed in the hope that it will be useful,
  11.   but WITHOUT ANY WARRANTY; without even the implied warranty of
  12.   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  13.   GNU General Public License for more details.
  14.  
  15.   You should have received a copy of the GNU General Public License
  16.   along with this program; if not, write to the Free Software
  17.   Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  18. ************************************************************************
  19.     HA arithmetic coder
  20. ***********************************************************************/
  21.  
  22. /***********************************************************************
  23. This file contains some small changes made by Nico de Vries (AIP-NL)
  24. allowing it to be compiled with Borland C++ 3.1.
  25. ***********************************************************************/
  26.  
  27.  
  28. #include <stdlib.h>
  29. #include <stdio.h>
  30. #include "ha.h"
  31. #include "haio.h"
  32. #include "acoder.h"
  33.  
  34. static U16B h,l,v;
  35. static S16B s;
  36. static S16B gpat,ppat;
  37.  
  38. /***********************************************************************
  39.   Bit I/O
  40. ***********************************************************************/
  41.  
  42. #define putbit(b)     { ppat<<=1;                \
  43.               if (b) ppat|=1;            \
  44.               if (ppat&0x100) {            \
  45.                 putbyte(ppat&0xff);        \
  46.                 ppat=1;                \
  47.               }                    \
  48.             }
  49.  
  50.  
  51. #define getbit(b)     { gpat<<=1;                \
  52.               if (!(gpat&0xff)) {            \
  53.                 gpat=getbyte();            \
  54.                 if (gpat&0x100) gpat=0x100;    \
  55.                 else {                \
  56.                     gpat<<=1;        \
  57.                     gpat|=1;        \
  58.                 }                \
  59.               }                    \
  60.               b|=(gpat&0x100)>>8;            \
  61.             }
  62.  
  63.  
  64. /***********************************************************************
  65.   Arithmetic encoding
  66. ***********************************************************************/
  67.  
  68. #ifndef __BORLANDC__
  69.  
  70. void ac_out(U16B low, U16B high, U16B tot) {
  71.     
  72.     register U32B r;
  73.     
  74.     r=(U32B)(h-l)+1;
  75.     h=(U16B)(r*high/tot-1)+l;
  76.     l+=(U16B)(r*low/tot);
  77.     if (!((h^l)&0x8000)) {
  78.     putbit(l&0x8000);
  79.     while(s) {
  80.         --s;
  81.         putbit(~l&0x8000);
  82.     }
  83.     l<<=1;
  84.     h<<=1;
  85.     h|=1;
  86.     while (!((h^l)&0x8000)) {
  87.         putbit(l&0x8000);
  88.         l<<=1;
  89.         h<<=1;
  90.         h|=1;
  91.     }
  92.     }
  93.     while ((l&0x4000)&&!(h&0x4000)) {
  94.     ++s;
  95.     l<<=1;
  96.     l&=0x7fff;
  97.     h<<=1;
  98.     h|=0x8001;
  99.     }
  100. }
  101.  
  102. #else
  103.  
  104. void ac_out(U16B low, U16B high, U16B tot) {
  105.  
  106.     asm {
  107.     mov ax,h
  108.     mov bx,l
  109.     sub ax,bx
  110.     add ax,1
  111.     mov cx,ax
  112.         jc  aco0
  113.     mul high
  114.         jmp aco1
  115.     }
  116. aco0:
  117.     asm {
  118.         mov dx,high
  119.     }
  120. aco1:
  121.     asm {
  122.         cmp dx,tot
  123.     je  aco2
  124.         div tot
  125.         sub ax,1
  126.         jmp aco3
  127.     }
  128. aco2:
  129.     asm {
  130.     mov ax,0xffff
  131.     }
  132. aco3:
  133.     asm {
  134.         add ax,bx
  135.     mov h,ax
  136.     mov ax,cx
  137.     cmp ax,0
  138.         je  aco4
  139.         mul low
  140.         jmp aco5
  141.     }
  142. aco4:
  143.     asm {
  144.         mov dx,low
  145.     }
  146. aco5:
  147.     asm {
  148.     div tot
  149.     add l,ax
  150.     }
  151.     if (!((h^l)&0x8000)) {
  152.     putbit(l&0x8000);
  153.     while(s) {
  154.         --s;
  155.         putbit(~l&0x8000);
  156.     }
  157.     l<<=1;
  158.     h<<=1;
  159.     h|=1;
  160.     while (!((h^l)&0x8000)) {
  161.         putbit(l&0x8000);
  162.         l<<=1;
  163.         h<<=1;
  164.         h|=1;
  165.     }
  166.     }
  167.     while ((l&0x4000)&&!(h&0x4000)) {
  168.     ++s;
  169.     l<<=1;
  170.     l&=0x7fff;
  171.     h<<=1;
  172.     h|=0x8001;
  173.     }
  174. }
  175.  
  176. #endif
  177.  
  178. void ac_init_encode(void) {
  179.  
  180.     h=0xffff;
  181.     l=s=0;
  182.     ppat=1;
  183. }
  184.  
  185. void ac_end_encode(void) {
  186.  
  187.     ++s;
  188.     putbit(l&0x4000);
  189.     while (s--) {
  190.     putbit(~l&0x4000);
  191.     }
  192.     if (ppat==1) {
  193.     flush();
  194.     return;
  195.     }
  196.     while(!(ppat&0x100)) ppat<<=1;
  197.     putbyte(ppat&0xff);
  198.     flush();
  199. }
  200.  
  201.  
  202. /***********************************************************************
  203.   Arithmetic decoding
  204. ***********************************************************************/
  205.  
  206. #ifndef __BORLANDC__
  207.  
  208. void ac_in(U16B low, U16B high, U16B tot) {
  209.  
  210.     register U32B r;
  211.  
  212.     r=(U32B)(h-l)+1;
  213.     h=(U16B)(r*high/tot-1)+l;
  214.     l+=(U16B)(r*low/tot);
  215.     while (!((h^l)&0x8000)) {
  216.     l<<=1;
  217.     h<<=1;
  218.     h|=1;
  219.     v<<=1;
  220.     getbit(v);
  221.     }
  222.     while ((l&0x4000)&&!(h&0x4000)) {
  223.     l<<=1;
  224.     l&=0x7fff;
  225.     h<<=1;
  226.     h|=0x8001;
  227.     v<<=1;
  228.     v^=0x8000;
  229.     getbit(v);
  230.     }
  231. }
  232.  
  233. U16B ac_threshold_val(U16B tot) {
  234.     
  235.     register U32B r;
  236.     
  237.     r=(U32B)(h-l)+1;
  238.     return (U16B)((((U32B)(v-l)+1)*tot-1)/r);
  239. }
  240.  
  241. #else
  242.  
  243. void ac_in(U16B low, U16B high, U16B tot) {
  244.  
  245.     asm {
  246.     mov ax,h
  247.     mov bx,l
  248.     sub ax,bx
  249.     add ax,1
  250.     mov cx,ax
  251.         jc  aci0
  252.     mul high
  253.         jmp aci1
  254.     }
  255. aci0:
  256.     asm {
  257.         mov dx,high
  258.     }
  259. aci1:
  260.     asm {
  261.         cmp dx,tot
  262.     je  aci2
  263.         div tot
  264.         sub ax,1
  265.         jmp aci3
  266.     }
  267. aci2:
  268.     asm {
  269.     mov ax,0xffff
  270.     }
  271. aci3:
  272.     asm {
  273.         add ax,bx
  274.     mov h,ax
  275.     mov ax,cx
  276.     cmp ax,0
  277.         je  aci4
  278.         mul low
  279.         jmp aci5
  280.     }
  281. aci4:
  282.     asm {
  283.         mov dx,low
  284.     }
  285. aci5:
  286.     asm {
  287.     div tot
  288.     add l,ax
  289.     }
  290.     while (!((h^l)&0x8000)) {
  291.     l<<=1;
  292.     h<<=1;
  293.     h|=1;
  294.     v<<=1;
  295.     getbit(v);
  296.     }
  297.     while ((l&0x4000)&&!(h&0x4000)) {
  298.     l<<=1;
  299.     l&=0x7fff;
  300.     h<<=1;
  301.     h|=0x8001;
  302.     v<<=1;
  303.     v^=0x8000;
  304.     getbit(v);
  305.     }
  306. }
  307.  
  308. U16B ac_threshold_val(U16B tot) {
  309.  
  310.     U16B rv;
  311.  
  312.     asm {
  313.     mov ax,h
  314.     sub ax,l
  315.     add ax,1
  316.     jc  atv1
  317.     mov cx,ax
  318.     mov ax,v
  319.     sub ax,l
  320.     inc ax
  321.     mul [tot]
  322.     sub ax,1
  323.     sbb dx,0
  324.     div cx
  325.     mov rv,ax
  326.     jmp atv3
  327.     }
  328. atv1:
  329.     asm {
  330.     mov ax,v
  331.     sub ax,l
  332.     add ax,1
  333.     jc  atv2
  334.     mul [tot]
  335.     sub ax,1
  336.     sbb dx,0
  337.     mov rv,dx
  338.     jmp atv3
  339.     }
  340. atv2:
  341.     asm {
  342.     mov ax,tot
  343.     dec ax
  344.     mov rv,dx
  345.     }
  346. atv3:
  347.     return rv;
  348. }
  349.  
  350. #endif
  351.  
  352. void ac_init_decode(void) {
  353.  
  354.     h=0xffff;
  355.     l=0;
  356.     gpat=0;
  357.     v=getbyte()<<8;
  358.     v|=0xff&getbyte();
  359. }
  360.  
  361.